package com.fs.web.base.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.fs.web.base.param.SysConstant;
import com.fs.web.base.utils.ApplicationUtils;
import com.fs.web.base.vo.LoginUser;
import com.fs.web.base.vo.SysPath;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;

/**
 * @author ACE
 * @desc 数据拦截器
 * @creationTime 2019-03-07 12:00
 * @projectName gps-root
 * @packageName com.fs.base.config
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer{
    @Setter
    @Getter
    @Value("${sysconfig.backExcludePath}")
    private String backExcludePath;
    @Setter
    @Getter
    @Value("${sysconfig.actuatorPath}")
    private String actuatorPath;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        /*
         * 1.session拦截处理
         */
        HandlerInterceptor sessionInterceptor = new HandlerInterceptorAdapter() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                if(sessionTimeout(request)){
                    if (request.getHeader("x-requested-with") != null &&
                            //异步请求超时的处理
                            "XMLHttpRequest".equalsIgnoreCase(request.getHeader("x-requested-with"))) {
                        PrintWriter wirter =  response.getWriter();
                        wirter.write("timeout"); wirter.flush(); wirter.close();
                    }else{
                        StringBuffer responseStr = new StringBuffer();
                        responseStr.append("<html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"/plug-in/layuiadmin/layui/css/layui.css\"/>");
                        //普通超时处理
                        if("/console".equals(request.getRequestURI())){
                            responseStr.append("<script type=\"text/javascript\">window.parent.document.location.href='")
                                    .append(SysPath.BACK_LOGIN_PATH).append("';</script></head>");

                        }else {
                            responseStr.append("<script type=\"text/javascript\" src=\"/plug-in/layuiadmin/layui/layui.all.js\"></script></head><body style='text-align:center;background-color:#EDEDED;'>")
                                    .append("<div style='margin-top:250;font-size : 2em;color : #535353;'>会话超时.请重新登录</div>")
                                    .append("<div style='margin:10 auto;padding:10;'><a href='javascript:void(0);' class='layui-btn'  onClick=\"")
                                    .append("window.parent.parent.document.location.href='")
                                    .append(SysPath.BACK_LOGIN_PATH).append("'\"")
                                    .append(">重新登录</a></div></body>");
                        }
                        responseStr.append("</html>");
                        response.setContentType("text/html;charset=UTF-8");
                        response.getWriter().print(responseStr);
                    }
                    return false;
                }else{
                    /*
                     * 将当前请求菜单动作传递到页面
                     */
                    String menuId = request.getParameter("menuId");
                    if(StringUtils.isNotBlank(menuId)){
                        String menuMotions = ApplicationUtils.getMenuMotions();
                        //JSONArray json = menuMotions.getJSONArray(menuId);
                        JSONArray json = JSON.parseObject(menuMotions).getJSONArray(menuId);
                        if(json == null) { json = new JSONArray(); }
                        request.setAttribute(SysConstant.PARAM_MENU_MOTIONS, json.toString());
                    }
                    return true;
                }
            }
        };

        /*
         * 免拦截路径
         */
        String[] excludePath = {};
        String[] actuatorPathArr = {};
        if(StringUtils.isNotBlank(backExcludePath)){ excludePath = backExcludePath.split(","); }
        if(StringUtils.isNotBlank(actuatorPath)){ actuatorPathArr = actuatorPath.split(","); }

         registry.addInterceptor(sessionInterceptor).addPathPatterns(SysPath.BACK_PATH.concat("/**"))
                .excludePathPatterns(SysPath.BACK_LOGIN_PATH)
                .excludePathPatterns(SysPath.BACK_LOGOUT_PATH)
                .excludePathPatterns(excludePath)
                .excludePathPatterns(actuatorPathArr);
        /*
         * 2.异常拦截处理
         */
        HandlerInterceptor exceptionInterceptor = new HandlerInterceptorAdapter() {
            @Override
            public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
                //TODO... Exception拦截器
                return true;
            }
        };
        registry.addInterceptor(exceptionInterceptor);

        /*
         * 3.日志拦截处理
         */
        HandlerInterceptor logInterceptor = new HandlerInterceptorAdapter() {

            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)throws Exception {
                //TODO... Log拦截器
                super.afterCompletion(request, response, handler, ex);
            }
        };
        registry.addInterceptor(logInterceptor);
    }

    private boolean  sessionTimeout(HttpServletRequest req){
        Boolean flag = false;
        LoginUser user = ApplicationUtils.getUser();
        if(user==null){
            flag = true;
        }
        return flag;
    }
}